import re
from django import http  # 注意这个是Django里面的http。很容易犯错
from django.contrib.auth import login, logout, authenticate
from django.db import DatabaseError
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from .models import Users
from mg.utils.excptions import Forbbiden  # 因为修改了文件的路径，所以要注意打包

class UserCenterView(View):
    def get(self,request):
        '''
        显示用户中心页面
        :param request:
        :return:
        '''
        return render(request, 'userapp/user_center.html')
        # if request.user.is_authenticated: # 里面的方法被装饰器修饰着，所以不用加括号（他这会返回True和False）
        #     return render(request,'userapp/user_center.html')
        # else:
        #     # 没有登录的话就重定向到新闻首页
        #     return redirect(reverse('newsapp:index'))


class LoginView(View):
    '''用户名登录视图'''

    def get(self, request):
        '''
        显示登录首页
        :param request:
        :return:
        '''
        next = request.GET.get('next','')
        return render(request, 'userapp/login.html',{'next':next})

    def post(self, request):
        '''
        回到后端处理登录的请求
        :param request:
        :return:
        '''
        # 接收next的参数
        next = request.POST.get('next','')
        # 1.接收参数
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        remember = request.POST.get('remember', '')
        # 2.校验参数（非空校验和格式校验）
        # 非空校验
        if not all([username, password, remember]):
            # 这个方式和raise差不多是一样的，不同的是HttpResponseForbidden是Django定义的，raise是自己定义的
            return http.HttpResponseForbidden('缺少必传参数')  # 禁止访问并报错

        # 判断⽤户名是否是5-8个字符（由于要实现多账号的登录，所以要把这里注销掉）
        # if not re.match(r'^[a-zA-Z][a-zA-Z0-9_]{4,7}$', username):
        #     # http.HttpResponseForbidden其实就是HttpResponse的效果
        #     return http.HttpResponseForbidden('请输⼊入5-8个字符的用户名')

        # 判断密码是否是3-8个字符
        if not re.match(r'^[0-9a-zA-Z]{3,8}$', password):
            return http.HttpResponseForbidden('请输⼊入3-8位的密码')

        # 3.认证参数是否正确（输入的用户名和密码是否正确）
        # Django有自带的认证方法
        user = authenticate(username=username,password=password)
        if user is None:
            return render(request,'userapp/login.html',{'login_error':'用户名或密码错误'})
        # 4.状态的保持
        login(request,user)

        # 设置状态保持的周期
        if remember != 'on':
        # 没有记住用户：浏览器会话结束就过期
            request.session.set_expiry(0)
        else:
        # 记住⽤用户：None表示两周后过期（session的默认保持时间14天后）
            request.session.set_expiry(None)
        # 判断是否有next的值，有的话直接跳转到next的页面
        if next:
            return redirect(next)

        # 5. 响应结果（重定向到新闻首页，前面定义了文件的路径，所以不用写具体（templates））
        return redirect(reverse('newsapp:index'))


class RegisterView(View):
    def get(self, request):
        # 直接渲染register.html模版引擎
        return render(request, 'userapp/register.html')

    def post(self, request):  # 提交表单之后会跳转的请求
        # 接收请求参数（表单参数）
        username = request.POST.get('username', '')
        phone = request.POST.get('phone', '')
        password = request.POST.get('password', '')

        # 校验参数（格式，完整参数）
        # 判断参数是否⻬齐全
        if not all([username, password, phone]):
            raise Forbbiden('缺少必传参数')
        # 判断⽤用户名是否是5-8个字符
        if not re.match(r'^[a-zA-Z][a-zA-Z0-9_]{4,7}$', username):
            raise Forbbiden('请输⼊入5-8个字符的⽤用户名')
        # 判断密码是否是3-8个字符
        if not re.match(r'^[0-9a-zA-Z]{3,8}$', password):
            raise Forbbiden('请输⼊入3-8位的密码')
        # 判断⼿手机号是否合法
        if not re.match(r'^1[3589]\d{9}$', phone):
            raise Forbbiden('请输⼊入正确的⼿手机号码')

        # 保存注册数据（入库）
        try:
            user = Users.objects.create_user(username=username, password=password, phone=phone)
        except DatabaseError:
            # 这里是跳转到register.html为他加一个值，进行报错处理
            return render(request, 'userapp/register.html', {'reg_error_msg': '注册失败'})

        # 用户注册状态保持
        login(request, user)

        # 返回响应结果
        return redirect(reverse('newsapp:index'))


class UsernameCount(View):

    def get(self, request, username):
        '''
        查询用户名的记录数
        :param request:
        :param username:
        :return:
        '''
        # 把同名的数据的个数查出来
        count = Users.objects.filter(username=username).count()

        return JsonResponse({  # 返回的格式为Json数据
            'code': 200,  # 状态码
            'error_msg': 'ok',  # 状态
            'count': count  # 同名数据有几个
        })


class LogOut(View):
    def get(self, request):
        '''
        用户退出登录
        :param request:
        :return:
        '''
        # Django自带的有一个退出登录的功能
        logout(request)
        # 重定向到首页
        return redirect(reverse('newsapp:index'))


class PhoneCount(View):
    def get(self, request, phone):
        '''
        查询用户手机号有没有重复注册
        :param request:
        :return:
        '''
        # 把同名的数据的个数查出来
        count = Users.objects.filter(phone=phone).count()

        return JsonResponse({  # 返回的格式为Json数据
            'code': 200,  # 状态码
            'error_msg': 'ok',  # 状态
            'count': count  # 同名数据有几个
        })
